package web.eshop.order;


import application.MySession;
import domain.shop.BasketItem;
import domain.shop.DeliveryMethod;
import domain.shop.PayMethod;
import domain.shop.Product;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import service.facade.customer.ShopCustomerService;
import web.eshop.MultipleProductsEshopPage;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Display page, where customer can see complete order.
 * Customer can confirm order.
 */
public final class OrderPanel3 extends Panel {

    @SpringBean
    private ShopCustomerService customerService;
    @SpringBean
    private MySession mySession;

    OrderPanel3(String id, OrderPage parent) {
        super(id);
        IModel<List<BasketItem>> itemListModel = createItemListModel();

        add(new ListView<BasketItem>("itemList", itemListModel) {

            @Override
            protected void populateItem(final ListItem<BasketItem> item) {
                item.add(new Label("productName", new PropertyModel(item.getModel(), "name")));
                item.add(new Label("price", new PropertyModel(item.getModel(), "price")));
                item.add(new Label("multiplicity", new PropertyModel(item.getModel(), "multiplicity")));
            }
        });
        IModel<DeliveryMethod> deliveryMethodIModel = new LoadableDetachableModel<DeliveryMethod>() {
            @Override
            protected DeliveryMethod load() {
                return customerService.findDeliveryMethodById(mySession.getDeliveryMethodId());
            }
        };
        IModel<PayMethod> payMethodIModel = new LoadableDetachableModel<PayMethod>() {
            @Override
            protected PayMethod load() {
                return customerService.findPayMethodById(mySession.getPayMethodId());
            }
        };
        add(new Label("deliveryMethod", (deliveryMethodIModel.getObject().getName() + " (cena: " + deliveryMethodIModel.getObject().getPrice() + ")")));
        add(new Label("payMethod", payMethodIModel.getObject().getName()));
        final BigDecimal price = deliveryMethodIModel.getObject().getPrice();

        add(new Label("totalPrice", new AbstractReadOnlyModel<String>() {

            @Override
            public String getObject() {
                return mySession.getTotalPrice().add(price).toString();
            }
        }));
        add(new Form("acceptForm") {

            {
                add(new Button("acceptOrder") {

                    @Override
                    public void onSubmit() {
                        try {
                            customerService.createNewOrder();
                            getSession().info(getLocalizer().getString("order.completed", this));
                            setResponsePage(MultipleProductsEshopPage.class);
                        } catch (Exception ex) {
                            getSession().error(getLocalizer().getString("order.error", this));
                            Logger.getLogger(OrderPanel3.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                });
            }
        });
    }

    private LoadableDetachableModel<List<BasketItem>> createItemListModel() {
        return new LoadableDetachableModel<List<BasketItem>>() {

            @Override
            protected List<BasketItem> load() {
                Map<Long, Integer> basket = mySession.getBasket();
                List<BasketItem> basketItems = new ArrayList<BasketItem>();
                for (Long productId : basket.keySet()) {
                    Product product = customerService.findProductById(productId);
                    BasketItem basketItem = new BasketItem();
                    basketItem.setMultiplicity(basket.get(productId));
                    basketItem.setProduct(product);
                    basketItem.setPrice(product.getPrice());
                    basketItems.add(basketItem);
                }
                return basketItems;
            }
        };
    }
}
